
#pragma once

#include "Button.h"
#include "Panel.h"
#include "StaticText.h"
#include "../SuperTree.h"

class TreeEditor;
class TreeEditorEntry;

// =======================================================
//                   TreeEditorEntry
// =======================================================

class TreeEditorEntry : public Panel
{
	friend class TreeEditor;

	public:

		TreeEditorEntry( );
		virtual ~TreeEditorEntry();

		virtual void	Render					( bool bSelected = false );
		virtual void	Update					( );

		virtual bool	IsContainer				( )	const							{ return m_bIsContainer; }
		virtual bool	UserCanDelete			( )	const							{ return m_bUserCanDelete; }

		virtual void	SetImage				( const u_int uTextureHash );
		virtual void	SetText					( const char* szText );
		virtual void	SetIsContainer			( const bool bIsContainer );

		virtual void	SetUserCanDelete		( const bool bCanDelete );
		virtual void	SetUserCanDuplicate		( const bool bCanDuplicate );

		virtual void	SetPosition				( const u_int uX, const u_int uY );

		virtual bool	MouseClickShouldSelect	( ) const;

		virtual bool IsExpanded( ) const { return m_bIsExpanded; }

	protected:
	
		// This stuff is used by the TreeEditor (protected just to differentiate it)

		enum BUTTON
		{
			BUTTON_DELETE = 0,
			BUTTON_DUPLICATE,
			BUTTON_EXPAND,

			NUM_BUTTONS
		};

		virtual void SetIndentation( const u_int uIndent );
		virtual bool IsFlaggedToDelete( ) const { return m_bIsFlaggedToDelete; }
		virtual bool IsFlaggedToDuplicate( ) const { return m_bIsFlaggedToDuplicate; }
		virtual void ClearDuplicateFlag( ) { m_bIsFlaggedToDuplicate = false; }

	private:
		
		virtual void RepositionButtons			( );

		static void ExpandButtonPressed			( void* pUserData );
		void _ExpandButtonPressed				( );

		static void DeleteButtonPressed			( void* pUserData );
		void _DeleteButtonPressed				( );

		static void DuplicateButtonPressed		( void* pUserData );
		void _DuplicateButtonPressed			( );

		Panel* m_pxImage;
		StaticText* m_pxLabel;

		Button* m_pxButtons[NUM_BUTTONS];

		ButtonPressCallback m_pfnExpandButtonCallback;
		void* m_pExpandButtonCallbackData;

		bool m_bIsContainer;
		bool m_bIsExpanded;
		bool m_bUserCanDelete;
		bool m_bUserCanDuplicate;

		bool m_bIsFlaggedToDelete;
		bool m_bIsFlaggedToDuplicate;

		u_int m_uIndentation;
};

// =======================================================
//                       TreeEditor
// =======================================================

typedef void (*TreeEditorActionCallback)( const FHandle xHandle );

class TreeEditor : public Panel
{
	public:

		// ___________________ Functions _______________________

		TreeEditor( Widget* pxParent );
		virtual ~TreeEditor();
	
		virtual void Clear();

		virtual void Render( );
		virtual void Update( );

		virtual void SetInsertionMarker( FHandle xHandle );
		virtual void ClearInsertionMarker();
		virtual FHandle GetInsertionMarker() { return m_xInsertionMarker; }
		
		virtual FHandle InsertTreeItem( const char* szLabel, const FHandle xSpecifyHandle = INVALID_HANDLE  );
		virtual void MoveTreeItem( const FHandle xHandle, const FHandle xNewParent = TREE_HANDLE_HEAD, const FHandle xMoveAfter = INVALID_HANDLE );

		virtual bool CanHaveChildren( ) { return false; }

		virtual TreeEditorEntry* GetTreeItem( const FHandle xHandle );

		virtual void SetOnDeleteCallback( TreeEditorActionCallback pfnCallback );
		virtual void SetOnDuplicateCallback( TreeEditorActionCallback pfnCallback );
		virtual void SetOnSelectionCallback( TreeEditorActionCallback pfnCallback );

		virtual void SetSelection( const FHandle xHandle );
		virtual FHandle GetSelection();

		virtual FHandle GetEntryUnderCursor();
		virtual FHandle GetLastEntry();

	private:

		// ___________________ Functions _______________________

		TreeEditorEntry* FindEntry ( TreeEditorEntry* pxStartPoint, const u_int uHandle );

		void RenderEntry ( TreeEditorEntry* pxEntry, u_int uIndent, u_int& uYPos, bool bSelected );

		static bool RenderItems_RecurseCallback( const TreeEditorEntry* pxEntry );

		// ___________________ Variables _______________________

		SuperTree<TreeEditorEntry>* m_pxTreeEditorItems;
		FHandle m_xSelectedEntry;
		FHandle m_xInsertionMarker;

		TreeEditorActionCallback m_pfnOnDeleteCallback;
		TreeEditorActionCallback m_pfnOnDuplicateCallback;
		TreeEditorActionCallback m_pfnOnSelectionCallback;
};

// eof
